{
 "metadata": {},
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "SWIG and Numpy\n",
      "==============\n",
      "\n",
      "Please note that with current versions of NumPy (SVN), the directory\n",
      "contains a complete working example with simple SWIG typemaps, including\n",
      "also a proper file so you can install it with the standard Python\n",
      "mechanisms. This should help you get up and running quickly.\n",
      "\n",
      "To get the feel how to write a truly minimalist interface, below is a\n",
      "relevant part of the simple SWIG interface file [umfpack.i](files/attachments/SWIG_and_NumPy/umfpack.i)\n",
      "(this is for SWIG \\< version 1.3.29) used to wrap the UMFPACK sparse\n",
      "linear solver libraries. The full interface can be found in the\n",
      "directory in the SciPy SVN repository. If you're using SWIG \\> version\n",
      "1.3.29, refer to the file in SciPy SVN repository, which is slightly\n",
      "different."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "/*!\n",
      "  Gets PyArrayObject from a PyObject.\n",
      "*/\n",
      "PyArrayObject *helper_getCArrayObject( PyObject *input, int type,\n",
      "\t\t\t\t       int minDim, int maxDim ) {\n",
      "  PyArrayObject *obj;\n",
      "\n",
      "  if (PyArray_Check( input )) {\n",
      "    obj = (PyArrayObject *) input;\n",
      "    if (!PyArray_ISCARRAY( obj )) {\n",
      "      PyErr_SetString( PyExc_TypeError, \"not a C array\" );\n",
      "      return NULL;\n",
      "    }\n",
      "    obj = (PyArrayObject *)\n",
      "      PyArray_ContiguousFromAny( input, type, minDim, maxDim );\n",
      "    if (!obj) return NULL;\n",
      "  } else {\n",
      "    PyErr_SetString( PyExc_TypeError, \"not an array\" );\n",
      "    return NULL;\n",
      "  }\n",
      "  return obj;\n",
      "}\n",
      "%}\n",
      "\n",
      "/*!\n",
      "  Use for arrays as input arguments. Could be also used for changing an array\n",
      "  in place.\n",
      "\n",
      "  @a rtype ... return this C data type\n",
      "  @a ctype ... C data type of the C function\n",
      "  @a atype ... PyArray_* suffix\n",
      "*/\n",
      "#define ARRAY_IN( rtype, ctype, atype ) \\\n",
      "%typemap( python, in ) (ctype *array) { \\\n",
      "  PyArrayObject *obj; \\\n",
      "  obj = helper_getCArrayObject( $input, PyArray_##atype, 1, 1 ); \\\n",
      "  if (!obj) return NULL; \\\n",
      "  $1 = (rtype *) obj->data; \\\n",
      "  Py_DECREF( obj ); \\\n",
      "};\n",
      "\n",
      "ARRAY_IN( int, const int, INT )\n",
      "%apply const int *array {\n",
      "    const int Ap [ ],\n",
      "    const int Ai [ ]\n",
      "};\n",
      "\n",
      "ARRAY_IN( long, const long, LONG )\n",
      "%apply const long *array {\n",
      "    const long Ap [ ],\n",
      "    const long Ai [ ]\n",
      "};\n",
      "\n",
      "ARRAY_IN( double, const double, DOUBLE )\n",
      "%apply const double *array {\n",
      "    const double Ax [ ],\n",
      "    const double Az [ ],\n",
      "    const double B [ ]\n",
      "};\n",
      "\n",
      "ARRAY_IN( double, double, DOUBLE )\n",
      "%apply double *array {\n",
      "    double X [ ]\n",
      "};"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The function being wrapped then could be like:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "int umfpack_di_solve( int sys, const int Ap [ ], const int Ai [ ],\n",
      "                      const double Ax [ ], double X [ ], const double B [ ],\n",
      "                      ... );"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    }
   ],
   "metadata": {}
  }
 ]
}
